#!/bin/bash
#
# install an build the latest ESP8266 OPEN SDK
# ASSUME Ubuntu 14.04LTS or 16.04LTS
# Mike Gore May 2017

# What: display a separator
# Example: sep
sep()
{
	echo "====================================================="
	echo
	echo
	echo
}

update_packages()
{

	sudo apt-get install make unrar-free autoconf automake \
		libtool libltdl7 libltdl-dev libtool-bin \
		gcc g++ gperf flex bison texinfo gawk ncurses-dev \
		libexpat-dev python-dev python python-serial \
		sed git unzip bash help2man wget bzip2 
	sep
}

# What: Echo ERROR: and arguments
# Arguments: $*
# Returns: Exit 1
# Example:
# fatal we failed 
fatal()
{
	echo "$*"; exit 1;
}

# What: Display the absolute path of a file - uses echo
# Arguments: path
# Notes: if argument is -bash then return absolute of current directory
# Example:
# absolute ~/file.txt
absolute()
{
	if [ -z "$1" ]
	then
		fatal " $FUNCNAME: missing argument: [$0]"
	fi

	# FIXME if the argument is -bash, then is this the correct course of action?
	if [ "$1" = "-bash" ]
	then
		echo -n "$(readlink -f \"`pwd`\")"
		return
	fi
	# Our full path name
	echo -n "$(readlink -f "$1")"
}

# What: Change directory and verify we actually end up there
# Argument: directory
# Notes: Useful if verifying permission of traget directory
# Example:
# check_cd /tmp/projects
check_cd()
{
	declare DIR="$1"
	echo "check_cd $DIR"
	declare P="`absolute \"$DIR\"`"
	if [ -z "$P" ]
	then
		fatal "$FUNCNAME: No directory"
	fi

    pushd "$P"

	declare PWD=$(pwd)
	if [ "$PWD" != "$P" ]
	then
			fatal "Can NOT change directory to [$P]"
	fi
}


check_dir()
{
	declare i
	for i in $*
	do
		if [ ! -d "$i" ]
		then
			fatal "Directory:[$i] missing"
		fi
	done
}

check_files()
{
	declare i
	for i in $*
	do
		if [ ! -f "$i" ]
		then
			fatal "Directory:[$i] missing"
		fi
	done
}


rm_path()
{
    export PATH
    export PATH=$(echo "$PATH" | sed -e "s,$1:,,g")
    export PATH=$(echo "$PATH" | sed -e "s/^://g" | sed -e "s/::/:/g")
}

set_path()
{

	# See: https://nurdspace.nl/ESP8266/First_setup
	# https://github.com/esp8266/esp8266-wiki/wiki/Toolchain

	export COMPILE=gcc
	export ROOT_DIR="/opt/Espressif"
	export SDK_BASE="$ROOT_DIR/esp-open-sdk"
	export SDK_HOME="$SDK_BASE/sdk"
	export SDK_BIN="$SDK_BASE/xtensa-lx106-elf/bin"

    # remove old SDK path
    rm_path "$SDK_BIN"
	export PATH="$SDK_BIN:$PATH"

	echo "COMPILE[$COMPILE]"
	echo "ROOT_DIR[$ROOT_DIR]"
	echo "SDK_BASE[$SDK_BASE]"
	echo "SDK_HOME[$SDK_HOME]"
	echo "SDK_BIN[$SDK_BIN]"
	sep
}


# Creaate a script that set the enviornment and edits the path when run
make_path()
{
    set_path

	cat <<EOF >"$SDK_BASE/setpath"
#!/bin/bash
#
rm_path()
{
    export PATH
    export PATH=\$(echo "\$PATH" | sed -e "s,\$1:,,g")
    export PATH=\$(echo "\$PATH" | sed -e "s/^://g" | sed -e "s/::/:/g")
}
# if we export SDK_BASE the compiles break - the sdk uses it somewhere
export COMPILE="$COMPILE"
export ROOT_DIR="$ROOT_DIR"
export SDK_BASE="$SDK_HOME"
export SDK_HOME="$SDK_HOME"
export SDK_BIN="$SDK_BIN"

rm_path "\$SDK_BIN"
export PATH="\$SDK_BIN:\$PATH"

EOF
	chmod 755 "$SDK_BASE/setpath"
	sep
}


#Save a list of libraries we can use in the sdk home directory
list_libs()
{
	LIST="sdk/lib xtensa-lx106-elf/xtensa-lx106-elf/sysroot/usr/lib xtensa-lx106-elf/xtensa-lx106-elf/sysroot/lib xtensa-lx106-elf/lib lx106-hal/src"

	for i in $LIST
	do
		if [ -d "$SDK_BASE"/$i ]
		then
			find "$SDK_BASE"/$i -type f | grep "\.a$" 
		fi
	done
}

install_open_sdk()
{
    set_path 

	echo Installing Open SDK
	check_cd $ROOT_DIR
        echo Target is $SDK_BASE
        declare DIR=$(basename $SDK_BASE)
        echo "DIR:[$DIR]"

        if [ ! -d "$SDK_BASE" ]
        then
            # Grab OPEN SDK 
            git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
            # Grab RTOS libraries and examples while we are at it
            git clone --recursive https://github.com/Superhouse/esp-open-rtos.git
            check_cd $SDK_BASE
                git submodule init
                git submodule update
                # for stand alone
                make STANDALONE=y
                # Need for RTOS version libs
                # make toolchain esptool libhal STANDALONE=n
                # Install SDK for all remaining include files and libraries not in the open SDK
                # make sdk
            popd	
        fi
        check_dir $SDK_BASE/esptool
        sep
    make_path 
    popd
}

add_tools()
{
	if [ -d "$SDK_HOME"/bin ]
	then
		cat $SDK_HOME/bin/blank.bin \
			$SDK_HOME/bin/blank.bin \
			$SDK_HOME/bin/blank.bin  >> $SDK_HOME/bin/clear_eep.bin
		check_dir $ROOT_DIR
		#get_git https://github.com/themadinventor esptool
		#cp -p esptool/*.py $SDK_HOME/tools
		chmod 755 $SDK_HOME/tools/*
	fi
}

#  ==============================================================


build_examples()
{
	echo Building Exampless
	check_cd $SDK_HOME
        get_git https://github.com/esp8266 source-code-examples
        if [ ! -d source-code-examples/blinky ]
        then
            echo "source-code-examples missing"
            exit 1
        fi

        check_cd source-code-examples/blinky
            sed -i -e "s;^XTENSA_TOOLS_ROOT.*$;XTENSA_TOOLS_ROOT=$SDK_BIN;" Makefile
            sed -i -e "s;^SDK_BASE.*$;SDK_BASE=$SDK_HOME/sdk;" Makefile
            sed -i -e "s;^EXTRA_INCDIR.*$;EXTRA_INCDIR= $SDK_HOME/include;" Makefile
            make clean
            make
            sep
        popd
    popd
}

build_nodemcu()
{
	echo "Building Nodemcu Firemware"
	check_cd "$ROOT_DIR"
        get_git https://github.com/nodemcu nodemcu-firmware
        check_cd "$ROOT_DIR/nodemcu-firmware"
            make
            sep
        popd
    popd
}



flash_nodemcu()
{
	echo "Flashinf Nodemcu Firemware"
 	check_cd "$ROOT_DIR/nodemcu-firmware"
        make flash
        sep
    popd
}

# ===================================================================


update_packages

install_open_sdk

make_path 

list_libs >"$SDK_BASE"/libs.txt

add_tools

#build_examples

#build_nodemcu
#flash_nodemcu

